package com.zhudi;

import java.io.*;
import java.net.*;
import java.util.*;

public class ClientHandler implements Runnable {
    private Socket socket;
    private String username;
    private BufferedReader in;
    private PrintWriter out;
    private Map<String, String> users;
    private Map<String, PrintWriter> onlineUsers;
    private Map<String, Group> groups;
    private FriendManager friendManager;
    private static final String CHAT_LOG_DIR = "chat_logs";

    public ClientHandler(Socket socket, Map<String, String> users, Map<String, PrintWriter> onlineUsers, Map<String, Group> groups) {
        this.socket = socket;
        this.users = users;
        this.onlineUsers = onlineUsers;
        this.groups = groups;
        this.friendManager = new FriendManager();
        new File(CHAT_LOG_DIR).mkdir(); // 创建存储聊天记录的目录
    }

    //todo：list 显示好友的这个功能会报错
    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);

            while (true) {
                out.println("Enter username:");
                String username = in.readLine();
                out.println("Enter password:");
                String password = in.readLine();

                if (users.containsKey(username) && users.get(username).equals(password)) {
                    this.username = username;
                    onlineUsers.put(username, out);
                    out.println("Login successful");
                    break;
                } else {
                    out.println("Invalid username or password");
                }
            }

            String message;
            while ((message = in.readLine()) != null) {
                if (message.startsWith("@")) {
                    handlePrivateMessage(message);
                } else if (message.startsWith("/group")) {
                    handleGroupMessage(message);
                } else if (message.startsWith("/friend")) {
                    handleFriendMessage(message);
                } else if (message.equals("/online")) {
                    handleOnlineStatus();
                } else if (message.startsWith("/log")) {
                    handleChatLog(message);
                } else {
                    broadcastMessage(message);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (username != null) {
                onlineUsers.remove(username);
            }
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void handlePrivateMessage(String message) {
        String[] parts = message.split(" ", 2);
        String targetUser = parts[0].substring(1);
        String privateMessage = parts[1];

        PrintWriter targetOut = onlineUsers.get(targetUser);
        if (targetOut != null) {
            targetOut.println(username + " (private): " + privateMessage);
            saveChatLog(username, targetUser, privateMessage);
        } else {
            out.println("User " + targetUser + " is not online.");
        }
    }

    private void handleGroupMessage(String message) {
        String[] parts = message.split(" ", 3);
        String command = parts[1];
        String groupName = parts[2];

        if (command.equals("create")) {
            groups.put(groupName, new Group(groupName));
            groups.get(groupName).addMember(username);
            out.println("Group " + groupName + " created.");
        } else if (command.equals("join")) {
            if (groups.containsKey(groupName)) {
                groups.get(groupName).addMember(username);
                out.println("Joined group " + groupName);
            } else {
                out.println("Group " + groupName + " does not exist.");
            }
        } else if (command.equals("msg")) {
            String groupMessage = parts[3];
            if (groups.containsKey(groupName)) {
                groups.get(groupName).sendMessage(username, groupMessage, onlineUsers);
                saveChatLog(username, groupName, groupMessage);
            } else {
                out.println("Group " + groupName + " does not exist.");
            }
        }
    }

    private void handleFriendMessage(String message) {
        String[] parts = message.split(" ", 3);
        String command = parts[1];
        String friendName = parts[2];

        if (command.equals("add")) {
            friendManager.addFriend(username, friendName);
            out.println("Added friend " + friendName);
        } else if (command.equals("list")) {
            Set<String> friendList = friendManager.getFriends(username);
            if (friendList != null) {
                out.println("Friends: " + String.join(", ", friendList));
            } else {
                out.println("No friends found.");
            }
        } else if (command.equals("remove")) {
            if (friendManager.removeFriend(username, friendName)) {
                out.println("Removed friend " + friendName);
            } else {
                out.println("Friend " + friendName + " not found.");
            }
        }
    }

    private void handleOnlineStatus() {
        out.println("Online users: " + String.join(", ", onlineUsers.keySet()));
    }

    private void broadcastMessage(String message) {
        for (PrintWriter writer : onlineUsers.values()) {
            writer.println(username + ": " + message);
        }
        saveChatLog(username, "ALL", message);
    }

    private void handleChatLog(String message) {
        String[] parts = message.split(" ", 3);
        String command = parts[1];

        if (command.equals("show")) {
            showChatLog();
        } else if (command.equals("delete")) {
            deleteChatLog();
        }
    }

    private void saveChatLog(String sender, String receiver, String message) {
        String logFileName = CHAT_LOG_DIR + "/" + sender + "-" + receiver + ".log";
        try (PrintWriter logWriter = new PrintWriter(new FileWriter(logFileName, true))) {
            logWriter.println(sender + ": " + message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void showChatLog() {
        File logDir = new File(CHAT_LOG_DIR);
        File[] logFiles = logDir.listFiles();
        if (logFiles != null) {
            for (File logFile : logFiles) {
                out.println("Chat log: " + logFile.getName());
                try (BufferedReader logReader = new BufferedReader(new FileReader(logFile))) {
                    String logLine;
                    while ((logLine = logReader.readLine()) != null) {
                        out.println(logLine);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            out.println("No chat logs found.");
        }
    }

    private void deleteChatLog() {
        File logDir = new File(CHAT_LOG_DIR);
        File[] logFiles = logDir.listFiles();
        if (logFiles != null) {
            for (File logFile : logFiles) {
                if (logFile.delete()) {
                    out.println("Deleted chat log: " + logFile.getName());
                } else {
                    out.println("Failed to delete chat log: " + logFile.getName());
                }
            }
        } else {
            out.println("No chat logs found.");
        }
    }
}